package pl.drypisy;


import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;

/**
 * Dialog for setting perspective. 
 * @author Marcin
 */
public class PerspectiveDialog extends javax.swing.JDialog {

    private PerspectiveProcess proc = new PerspectiveProcess();
    private BufferedImage image;
    private ImagePanel imgPanel;
    private AppControler ctrl;
    private CirclePanel cPanel;
    private double prop;
    
    public PerspectiveDialog(java.awt.Frame parent, boolean modal, BufferedImage img, AppControler c) {
        super(parent, modal);   
        initComponents();
        ctrl = c;
        imgPanel = ImagePanel.getSmallImagePanel(img);
        prop = (double)img.getWidth()/(double)imgPanel.getWidth();
        image = imgPanel.getImage();
        imgPanel.setSize(image.getWidth(),image.getHeight());
        lPanel.setSize(image.getWidth(),image.getHeight());
        lPanel.add(imgPanel,new Integer(0));
        cPanel = new CirclePanel();
        cPanel.setSize(image.getWidth(),image.getHeight());
        lPanel.add(cPanel,new Integer(1));
        setSize(image.getWidth()+ 50, image.getHeight() + 100);
    }
    
    public void makeLookahead(){
        int[] corners;
        corners = cPanel.getPerspectiveCorners();
        proc.setCorners(corners[0], corners[1],
                    corners[2], corners[3],
                    corners[4], corners[5],
                    corners[6], corners[7]);
        BufferedImage tmpImage = proc.process(image);
        int x = image.getWidth();
        int y = image.getHeight();
        for(DraggableCircle dc : cPanel.perspectiveFrameCircles){
            if(x > dc.getX()){
                x = dc.getX();
            }
            if(y > dc.getY()){
                y = dc.getY();
            }
        }
        imgPanel.setCords(x, y);
        imgPanel.setImage(tmpImage);
    }

    /**
     * @author Adam Syrek (changes: Marcin Piłat)
     */
    private class CirclePanel extends JPanel{
        private final int circleSize = 20;
        private DraggableCircle[] perspectiveFrameCircles;
        private int actualCircleIndex = -1;
        
        public CirclePanel() {
            setBackground(new Color(0,0,0,0));
            setOpaque(false);
            drawPerspectiveFrame();
            this.addMouseMotionListener(new MouseMotionListener() {
                @Override
                public void mouseDragged(MouseEvent e) {
                    if(actualCircleIndex != -1) {
                        perspectiveFrameCircles[actualCircleIndex].setX(e.getX());
                        perspectiveFrameCircles[actualCircleIndex].setY(e.getY());
                        makeLookahead();
                        getParent().repaint();
                        repaint();
                    }
                }
                @Override
                public void mouseMoved(MouseEvent e) {
                }
            });
            this.addMouseListener(new MouseListener() {
                @Override
                public void mouseClicked(MouseEvent e) {
                }

                @Override
                public void mousePressed(MouseEvent e) {
                    if(actualCircleIndex == -1) {
                        for(int i=0; i< perspectiveFrameCircles.length; ++i){
                            if(perspectiveFrameCircles[i].isOnCircle(e.getX(), e.getY())){
                                perspectiveFrameCircles[i].setX(e.getX());
                                perspectiveFrameCircles[i].setY(e.getY());
                                actualCircleIndex = i;
                                repaint();
                                return;
                            }
                        }
                    }
                }
                @Override
                public void mouseReleased(MouseEvent e) {
                    actualCircleIndex = -1;
                }
                @Override
                public void mouseEntered(MouseEvent e) {}
                @Override
                public void mouseExited(MouseEvent e) {
                    actualCircleIndex = -1;
                }
            });
        }
        private void drawPerspectiveFrame(){
            perspectiveFrameCircles = new DraggableCircle[4];
            perspectiveFrameCircles[0] = new DraggableCircle(0,0,circleSize);
            //g2d.drawOval(0, 0, circleSize, circleSize);
            perspectiveFrameCircles[1] = new DraggableCircle(image.getWidth(), 0, circleSize);
            //g2d.drawOval(image.getWidth() - circleSize, 0, circleSize, circleSize);
            perspectiveFrameCircles[2] = new DraggableCircle(image.getWidth(), image.getHeight(), circleSize);
            //g2d.drawOval(image.getWidth() - circleSize, image.getHeight() - circleSize, circleSize, circleSize);
            perspectiveFrameCircles[3] = new DraggableCircle(0, image.getHeight(), circleSize);
            //g2d.drawOval(0, image.getHeight() - circleSize, circleSize, circleSize);

        }
        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            g2d.setColor(new Color(99, 131, 255));
            for(DraggableCircle c : perspectiveFrameCircles)
            {
                c.draw(g2d);
            }
            g2d.drawLine(perspectiveFrameCircles[0].getX(), perspectiveFrameCircles[0].getY(), perspectiveFrameCircles[1].getX(), perspectiveFrameCircles[1].getY());
            g2d.drawLine(perspectiveFrameCircles[0].getX(), perspectiveFrameCircles[0].getY(), perspectiveFrameCircles[3].getX(), perspectiveFrameCircles[3].getY());
            g2d.drawLine(perspectiveFrameCircles[2].getX(), perspectiveFrameCircles[2].getY(), perspectiveFrameCircles[3].getX(), perspectiveFrameCircles[3].getY());
            g2d.drawLine(perspectiveFrameCircles[2].getX(), perspectiveFrameCircles[2].getY(), perspectiveFrameCircles[1].getX(), perspectiveFrameCircles[1].getY());
            g2d.drawLine(perspectiveFrameCircles[0].getX(), perspectiveFrameCircles[0].getY(), perspectiveFrameCircles[2].getX(), perspectiveFrameCircles[2].getY());
            g2d.drawLine(perspectiveFrameCircles[1].getX(), perspectiveFrameCircles[1].getY(), perspectiveFrameCircles[3].getX(), perspectiveFrameCircles[3].getY());
        }
        public int[] getPerspectiveCorners() {
            int[] tmp = new int[8];
            for(int i=0; i< perspectiveFrameCircles.length; ++i){
                tmp[i*2] = perspectiveFrameCircles[i].getX();
                tmp[i*2 + 1] = perspectiveFrameCircles[i].getY();
            }
            return tmp;
        }
    }
    
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jButton1 = new javax.swing.JButton();
        lPanel = new javax.swing.JLayeredPane();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

        jButton1.setText("Zmień perspektywe");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(lPanel)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(0, 255, Short.MAX_VALUE)
                        .addComponent(jButton1)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jButton1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(lPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 350, Short.MAX_VALUE)
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
        int[] corners = cPanel.getPerspectiveCorners();
        for(int i =0 ; i < 8; ++i){
            corners[i] = (int)((double)corners[i]*prop);
        }
        proc.setCorners(corners[0], corners[1],
                    corners[2], corners[3],
                    corners[4], corners[5],
                    corners[6], corners[7]);
        ctrl.setProcess(proc);
        ctrl.process();
        dispose();
    }//GEN-LAST:event_jButton1ActionPerformed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButton1;
    private javax.swing.JLayeredPane lPanel;
    // End of variables declaration//GEN-END:variables
}
